import 'dart:io';

import 'package:dio/dio.dart';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:intl/intl.dart';
import 'package:photo_frame/base/AbsLifecycleState.dart';
import 'package:photo_frame/dialog/bind_frame_dialog.dart';
import 'package:photo_frame/dialog/share_frame_dialog.dart';
import 'package:photo_frame/net/http_manager.dart';
import 'package:photo_frame/net/model/frame_info_model.dart';
import 'package:photo_frame/provider/frames_provider.dart';
import 'package:photo_frame/router/router_context.dart';
import 'package:photo_frame/utils/a_logger.dart';
import 'package:photo_frame/utils/localization_util.dart';
import 'package:photo_frame/widgets/app_bar_widget.dart';
import 'package:provider/provider.dart';

class DeviceListPage extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => _DeviceListPageState();
}

class _DeviceListPageState extends AbsLifecycleState<DeviceListPage>
    with AutomaticKeepAliveClientMixin {
  GlobalKey<RefreshIndicatorState> _refreshIndicatorStateKey = GlobalKey();
  DeviceListViewModel _vm = DeviceListViewModel();

  @override
  void onResume() {
    super.onResume();
    _refreshIndicatorStateKey.currentState?.show();
  }

  @override
  Widget build(BuildContext context) {
    super.build(context);
    return Scaffold(
      backgroundColor: Color(0xffF2F2F2),
      appBar: commonAppBar(
          AppLocalizationsWrapper.instance.unwrap(context).device,
          hideBack: true,
          actions: [
            CupertinoButton(
              padding: EdgeInsets.zero,
              onPressed: () {
                _showAddFrameDialog(context).then((_) {
                  _refreshIndicatorStateKey.currentState?.show();
                });
              },
              child: actionTextWidget(
                  AppLocalizationsWrapper.instance.unwrap(context).addDevice),
            )
          ]),
      body: SafeArea(
        child: RefreshIndicator(
          color: Color(0xff3F74EF),
          key: _refreshIndicatorStateKey,
          onRefresh: () =>
              context.read<FramesViewModel>().fetch().catchError((e) {
            print(e);
            Fluttertoast.showToast(
                msg: AppLocalizationsWrapper.instance.unwrap(context).netError);
          }),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Padding(
                padding:
                    const EdgeInsets.symmetric(horizontal: 15, vertical: 14)
                        .copyWith(bottom: 8.5),
                child: Text(
                  AppLocalizationsWrapper.instance.unwrap(context).deviceList,
                  style: TextStyle(color: Color(0xff999999), fontSize: 12),
                ),
              ),
              Expanded(
                flex: 1,
                child: Selector<FramesViewModel, List<FrameInfoModel>?>(
                  builder: (BuildContext context, List<FrameInfoModel>? frames,
                      Widget? child) {
                    return ListView.separated(
                        itemBuilder: (BuildContext context, int index) {
                          return frames?.isEmpty == true
                              ? _emptyItemWidget()
                              : _frameItemWidget(frames![index], index);
                        },
                        padding:
                            EdgeInsets.symmetric(vertical: 11, horizontal: 15),
                        separatorBuilder: (BuildContext context, int index) =>
                            SizedBox(
                              height: 11,
                            ),
                        itemCount: frames?.isEmpty == true
                            ? 1
                            : (frames?.length ?? 0));
                  },
                  selector: (_, vm) => vm.frames,
                  shouldRebuild: (n1, n2) => n1 != n2,
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }

  _frameItemWidget(FrameInfoModel frameInfo, int idx) {
    return CupertinoButton(
      padding: EdgeInsets.zero,
      onPressed: () {
        _showActionSheet(frameInfo.frame_id);
      },
      child: Container(
        decoration: BoxDecoration(
          color: Colors.white,
          borderRadius: BorderRadius.circular(9),
        ),
        height: 70,
        child: ListTile(
          leading: Image.asset(
              frameInfo.status == 1
                  ? "images/icon_frame_selected.png"
                  : "images/icon_frame_unselected.png",
              width: 58,
              height: 40),
          title: Text(frameInfo.name ?? ""),
          subtitle: Row(
            children: [
              Container(
                width: 10,
                height: 10,
                decoration: BoxDecoration(
                    color:
                        Color(frameInfo.status == 1 ? 0xff3ad953 : 0xffD8D8D8),
                    borderRadius: BorderRadius.circular(5)),
              ),
              SizedBox(
                width: 8,
              ),
              Text(
                frameInfo.status == 1
                    ? AppLocalizationsWrapper.instance.unwrap(context).online
                    : AppLocalizationsWrapper.instance.unwrap(context).offline,
                style: TextStyle(color: Color(0xff999999), fontSize: 12),
              )
            ],
          ),
          trailing: Image.asset(
            "images/icon_device_more.png",
            width: 22,
            height: 22,
          ),
        ),
      ),
    );
  }

  _emptyItemWidget() {
    return Column(
      children: [
        Container(
          width: 276.5,
          margin: EdgeInsets.only(top: 89.5),
          child: AspectRatio(
            aspectRatio: 2.3,
            child: Image.asset(
              "images/icon_device_empty.png",
            ),
          ),
        ),
        SizedBox(height: 38),
        RichText(
          text: TextSpan(
            children: [
              TextSpan(
                text: AppLocalizationsWrapper.instance
                    .unwrap(context)
                    .deviceEmptyPrefix,
                style: TextStyle(
                  color: Color(0xff333333),
                  fontSize: 12.0,
                ),
              ),
              TextSpan(
                text: AppLocalizationsWrapper.instance
                    .unwrap(context)
                    .deviceEmptyCenter,
                style: TextStyle(
                    color: Color(0xff333333),
                    fontSize: 12.0,
                    fontWeight: FontWeight.bold),
              ),
              TextSpan(
                text: AppLocalizationsWrapper.instance
                    .unwrap(context)
                    .deviceEmptySuffix,
                style: TextStyle(
                  color: Color(0xff333333),
                  fontSize: 12.0,
                ),
              )
            ],
          ),
        ),
        _emptyAddFrameWidget()
      ],
    );
  }

  _emptyAddFrameWidget() {
    return CupertinoButton(
      padding: EdgeInsets.zero,
      onPressed: () {
        _showAddFrameDialog(context).then((_) {
          _refreshIndicatorStateKey.currentState?.show();
        });
      },
      child: Container(
        height: 70,
        margin: EdgeInsets.only(top: 74.5, left: 15, right: 15),
        decoration: BoxDecoration(
          borderRadius: BorderRadius.circular(9),
          color: Colors.white,
        ),
        child: Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Image.asset(
              "images/icon_add_frame.png",
              width: 26,
              height: 21,
            ),
            SizedBox(width: 16),
            Text(
              AppLocalizationsWrapper.instance.unwrap(context).addFrame,
              style: TextStyle(color: Color(0xff333333), fontSize: 16),
            )
          ],
        ),
      ),
    );
  }

  _showActionSheet(String? frameId) {
    showCupertinoModalPopup(
      context: context,
      builder: (_) => CupertinoActionSheet(
        cancelButton: CupertinoActionSheetAction(
          isDefaultAction: true,
          onPressed: (() {
            Navigator.pop(context);
          }),
          child: Text(
            AppLocalizationsWrapper.instance.unwrap(context).cancel,
            style: TextStyle(
                color: Colors.black,
                fontSize: 16,
                fontWeight: FontWeight.normal),
          ),
        ),
        actions: [
          _actionItem(
              AppLocalizationsWrapper.instance
                  .unwrap(context)
                  .sharePhotoFramePairingCode,
              "images/icon_share_code.png", () {
            _vm.getShareInfo(context, frameId).then((e) {
              ARouter.instance.pagePop();
              if (e != null) {
                showDialog(
                    context: context,
                    builder: (context) => ShareFrameDialog(e));
              }
            });
          }),
          _actionItem(
              AppLocalizationsWrapper.instance.unwrap(context).switchMode,
              "images/icon_switch_mode.png", () {
            ARouter.instance.pagePop();
            _showSwitchModeActionSheet(frameId);
          }),
          _actionItem(
              AppLocalizationsWrapper.instance
                  .unwrap(context)
                  .setBackgroundMusic,
              "images/icon_background_music.png", () {
            ARouter.instance.pagePop();
            _vm.setBackgroundMusic(context, frameId);
          }),
          _actionItem(
              AppLocalizationsWrapper.instance.unwrap(context).deletePhotoFrame,
              "images/icon_delete.png", () {
            _vm.unbind(context, frameId).then((e) {
              if (e) {
                ARouter.instance.pagePop();
                _refreshIndicatorStateKey.currentState?.show();
              }
            });
          })
        ],
      ),
    );
  }

  _showSwitchModeActionSheet(String? frameId) {
    showCupertinoModalPopup(
      context: context,
      builder: (context) => CupertinoActionSheet(
        cancelButton: CupertinoActionSheetAction(
          isDefaultAction: true,
          onPressed: (() {
            Navigator.pop(context);
          }),
          child: Text(
            AppLocalizationsWrapper.instance.unwrap(context).cancel,
            style: TextStyle(
                color: Colors.black,
                fontSize: 16,
                fontWeight: FontWeight.normal),
          ),
        ),
        actions: [
          _switchModeItem(
              AppLocalizationsWrapper.instance.unwrap(context).frameMode, () {
            _vm.switchMode(context, frameId, 1).then((e) {
              if (e == true) {
                Navigator.pop(context);
              }
            });
          }),
          _switchModeItem(
              AppLocalizationsWrapper.instance.unwrap(context).calendarMode,
              () {
            _vm.switchMode(context, frameId, 2).then((e) {
              if (e == true) {
                Navigator.pop(context);
              }
            });
          }),
          _switchModeItem(
              AppLocalizationsWrapper.instance.unwrap(context).galleryModel,
              () {
            _vm.switchMode(context, frameId, 3).then((e) {
              if (e == true) {
                Navigator.pop(context);
              }
            });
          })
        ],
      ),
    );
  }

  _actionItem(String name, String image, VoidCallback onPressed) {
    return Container(
      color: Colors.white,
      child: CupertinoActionSheetAction(
        onPressed: onPressed,
        child: Padding(
          padding: const EdgeInsets.only(left: 8.0),
          child: Row(
            children: [
              Image.asset(image, width: 27, height: 27),
              Padding(
                padding: const EdgeInsets.only(left: 8.0),
                child: Text(
                  name,
                  style: TextStyle(color: Color(0xff333333), fontSize: 14),
                ),
              )
            ],
          ),
        ),
      ),
    );
  }

  _switchModeItem(String name, VoidCallback onPressed) {
    return Container(
      color: Colors.white,
      child: CupertinoActionSheetAction(
        onPressed: onPressed,
        child: Center(
          child: Padding(
            padding: const EdgeInsets.only(left: 8.0),
            child: Text(
              name,
              style: TextStyle(color: Color(0xff333333), fontSize: 14),
            ),
          ),
        ),
      ),
    );
  }

  Future<void> _showAddFrameDialog(BuildContext context) {
    return showDialog(
        barrierDismissible: false,
        context: context,
        builder: (BuildContext context) => BindFrameDialog()).whenComplete(() {
      FocusManager.instance.primaryFocus?.unfocus();
    });
  }

  @override
  bool get wantKeepAlive => true;
}

class DeviceListViewModel extends ChangeNotifier {
  Future<ShareInfo?> getShareInfo(BuildContext context, String? frameId) {
    EasyLoading.show();
    return HttpManager.instance.doRequest("/api/gencode",
        parameters: {"frame_id": frameId}).then((e) async {
      if (e.isSuccess) {
        return ShareInfo(
            e.data!['bindcode'].toString(),
            DateFormat('yyyy-MM-dd HH:mm')
                .format(DateTime.now().add(Duration(minutes: 5))));
      }
    }).catchError((e) {
      print(e);
      Fluttertoast.showToast(
          msg: AppLocalizationsWrapper.instance.unwrap(context).netError);
    }).whenComplete(() {
      EasyLoading.dismiss();
    });
  }

  Future<bool?> switchMode(BuildContext context, String? frameId, num mode) {
    EasyLoading.show();
    return HttpManager.instance.doRequest("/api/playmode", parameters: {
      "frame_id": frameId,
      "mode": mode,
    }).then((e) async {
      if (e.isSuccess) {
        Fluttertoast.showToast(
            msg: e.isSuccess
                ? AppLocalizationsWrapper.instance
                    .unwrap(context)
                    .switchModeSuccessful
                : (e.msg ?? ""));
      }
      return e.isSuccess;
    }).catchError((e) {
      print(e);
      Fluttertoast.showToast(
          msg: AppLocalizationsWrapper.instance.unwrap(context).netError);
    }).whenComplete(() {
      EasyLoading.dismiss();
    });
  }

  setBackgroundMusic(BuildContext context, String? frameId) async {
    FilePickerResult? result = await FilePicker.platform.pickFiles(
      type: FileType.custom,
      allowedExtensions: [
        'wav',
        'aiff',
        'alac',
        'flac',
        'mp3',
        'aac',
        'wma',
        'ogg'
      ],
    );
    if (result != null) {
      EasyLoading.show();
      File file = File(result.files.single.path!);
      ALogger.i("setBackgroundMusic ${file.path}");
      var suffix = file.path.substring(file.path.lastIndexOf(".") + 1);
      HttpManager.instance.doRequest("/api/getuploadurl", parameters: {
        "id": file.path,
        "frame_id": frameId,
        "ext": ".$suffix",
      }).then((e) async {
        if (e.isSuccess && e.data?['url']?.toString().isNotEmpty == true) {
          var data = await file.readAsBytes();
          await HttpManager.instance.dio.put(
            e.data!['url'],
            options: Options(
              headers: {
                'Content-Type': 'audio/$suffix',
              },
            ),
            data: MultipartFile.fromBytes(data).finalize(),
          );
          uploadFinish([frameId ?? ""]);
          if (context.mounted) {
            Fluttertoast.showToast(
              msg: AppLocalizationsWrapper.instance
                  .unwrap(context)
                  .setupSuccessful,
            );
          }
        }
      }).catchError((e) {
        print(e);
        Fluttertoast.showToast(
            msg: AppLocalizationsWrapper.instance.unwrap(context).netError);
      }).whenComplete(() {
        EasyLoading.dismiss();
      });
    }
  }

  Future<bool> unbind(BuildContext context, String? frameId) {
    EasyLoading.show();
    return HttpManager.instance.doRequest("/api/unbind", parameters: {
      "frame_id": frameId,
    }).then((e) async {
      if (e.isSuccess) {
        Fluttertoast.showToast(
            msg: AppLocalizationsWrapper.instance
                .unwrap(context)
                .unbindSuccessful);
      }
      return e.isSuccess;
    }).catchError((e) {
      print(e);
      Fluttertoast.showToast(
          msg: AppLocalizationsWrapper.instance.unwrap(context).netError);
    }).whenComplete(() {
      EasyLoading.dismiss();
    });
  }
}
